<?php

namespace App\Services\User;

use App\Exceptions\LoginException;
use App\Helpers\MvcHelper;
use App\Helpers\Redis\RedisHelper;
use Exception;

class LoginService extends BaseUserService
{

    /**
     * 获取验证码
     *
     * @return array
     */
    public function captcha(): array
    {
        $resultData = captcha();

        // 缓存 5 分钟时间
        RedisHelper::set(RedisHelper::makeKey(RedisHelper::STRING_LOGIN_CAPTCHA, strtolower($resultData['captchaText'])), $resultData['captchaText'], ONE_MINUTE);

        $resultData['openCaptcha'] = true;

        return $resultData;
    }

    /**
     * 登录
     *
     * @param array $params
     * @return array
     * @throws LoginException
     * @throws Exception
     */
    public function login(array $params): array
    {
        // 检测验证码
        $this->_checkCaptcha($params['captcha']);

        // 查询用户信息
        $userData = $this->getUserModel()->getItemByUsername($params['username'], [
            'id', 'uuid', 'username', 'nickname', 'password', 'authority_id', 'side_mode', 'header_img', 'base_color', 'active_color', 'phone', 'email', 'enable',
        ]);
        if (empty($userData)) {
            throw new LoginException('用户名或密码错误', LoginException::CODE_1001);
        }
        if (!encryptionCheck($params['password'], $userData['password'])) {
            throw new LoginException('用户名或密码错误', LoginException::CODE_1001);
        }
        if ($userData['enable'] != 1) {
            throw new LoginException('登陆失败! 用户被禁止登录!', LoginException::CODE_1002);
        }

        // 查询用户身份
        $authorities = $this->getAuthoritiesModel()->getItemsByIds([$userData['authority_id']], [
            'id', 'name', 'default_router',
        ]);

        // 查询用户角色默认菜单是否存在
        $menuIds = $this->getAuthorityMenusModel()->getMenusIdsByAuthorityId($userData['authority_id']);
        // 查询menu
        $menusList = $this->getMenusModel()->getMenusList($authorities[0]['default_router'], $menuIds);
        if (empty($menusList)) {
            $userData['authorities']['default_router'] = '404';
        }

        $authorityList = [];
        foreach ($authorities as $item) {
            $authorityList[] = [
                'authorityId'   => $item['id'],
                'authorityName' => $item['name'],
                'defaultRouter' => $item['default_router'],
            ];
        }

        $userInfo = [
            'userId'      => $userData['id'],
            'uuid'        => $userData['uuid'],
            'nickName'    => $userData['nickname'],
            'username'    => $userData['username'],
            'authorityId' => $userData['authority_id'],
            'authority'   => $authorityList[0],
            'authorities' => $authorityList,
        ];

        // 生成登录 token       @tips 用户权限修改后需要重新登录
        $token = generateJwt($userInfo);

        return [
            'user'  => $userInfo,
            'token' => $token,
        ];
    }

    /**
     * 检测验证码
     *
     * @param string $captcha
     * @return void
     * @throws LoginException
     */
    private function _checkCaptcha(string $captcha): void
    {
        // 获取验证码
        try {
            $cacheCaptcha = RedisHelper::get(RedisHelper::makeKey(RedisHelper::STRING_LOGIN_CAPTCHA, strtolower($captcha)));
            if (empty($cacheCaptcha)) {
                throw new LoginException('验证码已失效', LoginException::CODE_1004);
            }

            if (strtolower($cacheCaptcha) != strtolower($captcha)) {
                throw new LoginException('验证码验证失败', LoginException::CODE_1005);
            }
        } catch (Exception $exception) {
            // 清除验证码
            RedisHelper::del(RedisHelper::makeKey(RedisHelper::STRING_LOGIN_CAPTCHA, strtolower($captcha)));
            throw $exception;
        }
    }

    /**
     * 退出登录 拉黑jwt
     *
     * @return void
     */
    public function logout(): void
    {
        jwtJoinBlackList(MvcHelper::getLoginToken(), MvcHelper::getLoginTokenExpire());
    }
}
